import hljs from 'highlight.js'

let oLangSelect: HTMLSelectElement | undefined = undefined,
  oThemeSelect: HTMLSelectElement | undefined = undefined,
  oCodeTextarea: HTMLTextAreaElement | undefined = undefined,
  oCodeBlock: HTMLElement | undefined = undefined,
  oCodeLink: HTMLLinkElement | undefined = undefined,
  selectLanguage: string = 'typescript'

// 自定义主题
const themeConfig = [
  { name: 'atom-one-dark', linkSrc: '/styles/atom-one-dark.min.css' },
  { name: 'dark', linkSrc: '/styles/dark.min.css' },
  { name: 'github-dark', linkSrc: '/styles/github-dark.min.css' }
]

const init = () => {
  initElement()
  initLanguage()
  initTheme()
  bindEvent()
  // 初始化高亮元素: 初始化一次
  hljs.highlightElement(oCodeBlock!)
  renderCodeBlock({ language: selectLanguage })
}

// 初始化
const initElement = () => {
  oLangSelect = document.getElementById('lang-select') as HTMLSelectElement
  oThemeSelect = document.getElementById('theme-select') as HTMLSelectElement
  oCodeTextarea = document.getElementById('code-text') as HTMLTextAreaElement
  oCodeBlock = document.getElementById('code-block') as HTMLElement
  oCodeLink = document.getElementById('code-link') as HTMLLinkElement
}

const initLanguage = () => {
  const listLang = hljs.listLanguages()
  const oFrag = document.createDocumentFragment()

  listLang.forEach(lang => {
    const oOption = document.createElement('option')
    oOption.value = lang
    oOption.textContent = lang
    oFrag.appendChild(oOption)
  })

  oLangSelect?.appendChild(oFrag)
}

const initTheme = () => {
  const oFrag = document.createDocumentFragment()

  themeConfig.forEach(({ name, linkSrc }) => {
    const oOption = document.createElement('option')
    oOption.value = linkSrc
    oOption.textContent = name
    oFrag.appendChild(oOption)
  })

  oThemeSelect?.appendChild(oFrag)
}

const bindEvent = () => {
  oCodeTextarea?.addEventListener('input', handleCodeInput, false)
  oLangSelect?.addEventListener('change', handleLangChange, false)
  oThemeSelect?.addEventListener('change', handleThemeChange, false)
}

// 代码输入
const handleCodeInput = (e: Event) => {
  const el = e.target as HTMLTextAreaElement

  if (el && oCodeBlock) {
    oCodeBlock.innerHTML = el.value
    renderCodeBlock({ language: selectLanguage })
  }
}

// 语言选择
const handleLangChange = (e: Event) => {
  const target = e.target as HTMLSelectElement,
    language = target.value

  if (oCodeBlock) {
    oCodeBlock.classList.remove(selectLanguage)
    oCodeBlock.classList.add(language)
    selectLanguage = language

    renderCodeBlock({ language: selectLanguage })
  }
}

// 主题选择
const handleThemeChange = (e: Event) => {
  const target = e.target as HTMLSelectElement,
    linkSrc = target.value
  
  if (oCodeLink) {
    oCodeLink.href = linkSrc
  }
}

// 高亮代码块
const renderCodeBlock = (opts: {
  language: string
}) => {
  if (oCodeBlock) {
    const highlightResult = hljs.highlight(oCodeBlock.textContent || '', {
      language: opts.language
    })

    // 格式化之后的内容填入：
    oCodeBlock.innerHTML = highlightResult.value
    console.log(highlightResult.value)
  }
}

window.addEventListener('DOMContentLoaded', () => init(), false)